//@author A0106044W
package logic;

import java.util.logging.*;

import commandInfo.AddCommandInfo;
import commandInfo.CommandInfo;
import commandInfo.RemoveCommandInfo;
import storage.Task;

/**
 * 
 * 
 * 	       Sothearith Sreang
 *         All of the Logic part is written by me.
 * 
 */

public class AddHandler extends OperationHandler {
	
	Task task;
	
	private static final String SUCCESSFUL_ADDING_MESSAGE = "The task with description \"%1s\" is successfully added";
	private static final String SUCCESSFUL_UNDO = "task with description \"%1s\" is now successfully removed";
	private static final String UNSUCCESSFUL_UNDO = "task cannot be found in storage. Problems with CommandHistory";

	private static final String EXCEPTION_NULL_TASK= "task parameter is null";
	
	
	// Two public constructors
	
	// This constructor is for user command's add operation
	public AddHandler(Task taskAtt){
		super();
		task = taskAtt;
	}
	
	// This constructor is for undo operation for the previous add operation
	public AddHandler(CommandInfo commandInfoP){
		super();
		setUpTask(commandInfoP);
	}

	// This method is for user command's add operation
	public String execute(){
		addTask();
		String feedback =  String.format(SUCCESSFUL_ADDING_MESSAGE, task.getDescription());		
		
		return feedback;
	}

	// This method is called by undo's add operation
	public String undo(){
		Task taskClone = getTaskClone();
		assert taskClone != null;
		
		removeTask(taskClone);
		String feedback = String.format(SUCCESSFUL_UNDO, taskClone.getDescription());
		
		return feedback;
	}
	
	
	// Next level abstraction
	
	// This method is called by AddHandler constructor
	private void setUpTask(CommandInfo commandInfoP) {
		Task taskClone = commandInfoP.getUpdatedTask();
		task = super.getTask(taskClone);
		assert task != null;
	}
	
	private Task getTaskClone() {
		Task taskClone = null;
		
		try{
			taskClone = task.cloneSelf();
		} catch (Exception e) {
			Logic.logger.log(Level.SEVERE, e.getMessage());
		}
		
		return taskClone;
	}
	
	private void addTask() {
		assert task != null;
		
		try{
			// this statement is to get the actual task if task gets duplicated (because storage will change task's description to avoid duplication)
			task = super.storage.addTask(task);
			super.commandInfo = new AddCommandInfo(task);
		} catch (Exception e) {
			Logic.logger.log(Level.SEVERE, EXCEPTION_NULL_TASK);
		}

	}
	
	private void removeTask(Task taskClone) {
		boolean isSuccess = false;
		
		try{
			isSuccess = super.storage.removeTask(task);
			
			if(isSuccess) {
				super.commandInfo = new RemoveCommandInfo(taskClone);
			} else {
				Logic.logger.log(Level.SEVERE, UNSUCCESSFUL_UNDO);
			}
			
		} catch (Exception e) {
			Logic.logger.log(Level.SEVERE, EXCEPTION_NULL_TASK);
		}
	}

	
}
